#ifndef __unix__
#include <windows.h>
#endif
#include <GL/glu.h>
#include <QColor>
#include <QSizePolicy>
#include <QtOpenGL/QtOpenGL>
#include "Drawing.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdio>
#include <math.h>


void Drawing::reset()
{
	cameraorientation[0] = cameraorientation[5] = cameraorientation[10] =cameraorientation[15] = 1;
	cameraorientation[1] = cameraorientation[2] = cameraorientation[3] =cameraorientation[4]
			=cameraorientation[6] = cameraorientation[7] = cameraorientation[8] =cameraorientation[9]
			=cameraorientation[11] = cameraorientation[12] = cameraorientation[13] =cameraorientation[14] =0;
	u[0]=v[1]=n[2]=1;
	u[1]=u[2]=v[0]=v[2]=n[1]=n[0]=0;

	for(int i=0;i<3;i++)
	{
		rotation[i]=0;
		translate[i]=0;
	}
	refresh();
}

void Drawing::CameraRotation()
{
	glPushMatrix();
	glMatrixMode(GL_MODELVIEW_MATRIX);
	glLoadIdentity();
	glRotatef(rotation[0],1,0,0);
	glRotatef(rotation[1],0,1,0);
	glRotatef(rotation[2],0,0,1);
	glMultMatrixf(cameraorientation);
	glGetFloatv(GL_MODELVIEW_MATRIX,cameraorientation);
	glPopMatrix();

	for(int i=0;i<3;i++)
	{
		u[i]=cameraorientation[4*i];
		v[i]=cameraorientation[4*i+1];
		n[i]=cameraorientation[4*i+2];
	}
}

Drawing::Drawing(QWidget *parent) :
	QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
	setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}

QSize Drawing::sizeHint() const
{
	return QSize(256, 256);
}

void Drawing::initializeGL()
{
	makeCurrent();
	glShadeModel(GL_SMOOTH);
	glClearColor(1.0,1.0,1.0,0.0);
	glClearDepth(1.0);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
}

void Drawing::paintGL()
{
	makeCurrent();
	//glUseProgram(0);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glMatrixMode(GL_MODELVIEW);

	glColor3ub(uipara->color[0],uipara->color[1],uipara->color[2]);
	glPolygonMode(GL_FRONT,uipara->primitive);
	glFrontFace(uipara->facefront);
	for(int i=0;i<inpara->trinum;i++)
	{
		glBegin(GL_TRIANGLES);
		glVertex3f(inpara->tri[i].v[0].pos[0],inpara->tri[i].v[0].pos[1],inpara->tri[i].v[0].pos[2]);
		glVertex3f(inpara->tri[i].v[1].pos[0],inpara->tri[i].v[1].pos[1],inpara->tri[i].v[1].pos[2]);
		glVertex3f(inpara->tri[i].v[2].pos[0],inpara->tri[i].v[2].pos[1],inpara->tri[i].v[2].pos[2]);
		glEnd();
	}
	glCullFace(GL_BACK);
}

void Drawing::resizeGL(int width, int height)
{
	makeCurrent();
	glViewport(0,0,width,height);
	glClearColor(0,0,0,0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt((inpara->pmax[0]+inpara->pmin[0])/2+translate[0],
			  (inpara->pmax[1]+inpara->pmin[1])/2+translate[1],
			  (inpara->pmax[2]+inpara->pmin[2])/2+translate[2]+inpara->distance,
			  (inpara->pmax[0]+inpara->pmin[0])/2+translate[0]-n[0],
			  (inpara->pmax[1]+inpara->pmin[1])/2+translate[1]-n[1],
			  (inpara->pmax[2]+inpara->pmin[2])/2+translate[2]+inpara->distance-n[2],
			  v[0],v[1],v[2]);
	/*
	GLfloat temp[16];
	glGetFloatv(GL_MODELVIEW_MATRIX,temp);
	std::cout<<"GM:";
	for(int ii =0; ii<16; ii++)
		std::cout<<temp[ii]<<' ';
	std::cout<<std::endl;
*/
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0,width/height,uipara->nearer,uipara->farer);
}

void Drawing::refresh()
{
	for(int i=0;i<3;i++){
		translate[i] = uipara->translation[0]*u[i]
				+uipara->translation[1]*v[i]
				+uipara->translation[2]*n[i];
	}
	if(uipara->rotated){
		cout << "rotate: ";
		for(int i = 0; i < 3; i++){
			rotation[i] = uipara->rotation[i] - uipara->rotationold[i];
			cout << rotation[i] << ',';
		}
		cout << endl;
		CameraRotation();
	}
	resizeGL(width(), height());
	updateGL();
}
